feat(node): add gear_readWasmCustomSection RPC endpoint#5275
feat(node): add gear_readWasmCustomSection RPC endpoint#5275
Conversation
Add a node-level RPC that reads custom sections from program WASM original code stored on-chain. This enables clients to retrieve Sails IDL v2 (or any named custom section) without original build artifacts. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Changed Files
|
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a new node-level RPC endpoint designed to improve developer experience by allowing clients to fetch custom sections from on-chain WASM programs. This is particularly useful for retrieving embedded metadata, such as Sails IDL, without requiring external build artifacts. The implementation includes robust utility functions for WASM parsing and ensures compatibility with historical block queries. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a new RPC endpoint gear_readWasmCustomSection to allow clients to retrieve custom sections from original WASM code stored on-chain, which is particularly useful for extracting Sails IDL data. It includes the necessary logic in gear-core to parse WASM binaries for specific sections and adds the RPC implementation in the node service. A critical issue was identified regarding the hardcoded pallet name GearProgram used for storage key construction, which likely conflicts with the actual pallet name Gear used in the runtime, potentially causing the RPC to always return null. Additionally, the manual construction of storage keys using the Identity hasher is noted as a fragile implementation detail.
Move inline crate paths to proper `use` imports for `gear_core::code::get_custom_section_data` and `parity_scale_codec::Decode`. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
@claude opus review |
|
Claude finished @ukint-vs's task in 3m 38s —— View job Claude Opus ReviewThe PR adds a node-service-level RPC Findings below. severity: medium — File: pub fn get_custom_section_data<'a>(
wasm: &'a [u8],
section_name: &str,
) -> Result<Option<&'a [u8]>, &'static str> {
let parser = wasmparser::Parser::new(0);
let mut saw_version = false;
for payload in parser.parse_all(wasm) {
let payload = payload.map_err(|_| "invalid wasm binary")?;
match payload {
Payload::Version { .. } => saw_version = true,
Payload::CustomSection(section) if section.name() == section_name => {
return Ok(Some(section.data()));
}
_ => {}
}
}
if !saw_version {
return Err("invalid wasm binary");
}
Ok(None)
}Two issues bundled:
severity: medium — verification gap: no end-to-end test for the RPC. The 5 unit tests cover
Given the PR's test plan has two items unchecked, I'd suggest at minimum a severity: low — tests use fully-qualified File: let mut module = wasm_encoder::Module::new();
let mut types = wasm_encoder::TypeSection::new();
types.ty().function(vec![], vec![]);
module.section(&types);
module.section(&wasm_encoder::CustomSection {
name: name.into(),
data: data.into(),
});Per severity: low — minor: File: The helper Notes / non-findings
SummaryOverall the change is sound and follows existing conventions. The most meaningful improvement would be an integration test that exercises the full RPC path, because the helper-level unit tests can't catch a storage-key or decoding regression. Secondary: clean up the |
- Drop the `saw_version` flag in `get_custom_section_data` — `parse_all`
already rejects input without a valid preamble, so the flag was
redundant. Return `wasmparser::BinaryReaderError` instead of
`&'static str` so parser offset + reason propagate through the RPC.
- Clean `wasm_encoder::*` prefixes out of the test module by importing
`Module`, `TypeSection`, `CustomSection` at the top.
- Consolidate the test helper into
`make_wasm_with_custom_sections(&[(&str, &[u8])])` so
`first_match_returned` shares it instead of inlining the module body.
- Add `Api::read_wasm_custom_section[_at]` in gsdk and a gsdk
integration test that round-trips a `@custom "sails:idl"` WAT via
`upload_code` + the RPC, covering the present, missing-section, and
unknown-`code_id` cases. This exercises the full storage-key path
(`twox_128("GearProgram") ++ twox_128("OriginalCodeStorage") ++ code_id`)
and the SCALE envelope decode.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
|
/review |
Apply review feedback from /simplify:
- node/service/src/rpc/wasm_section.rs:
- Collapse PhantomData<Block> + PhantomData<Backend> into a tuple field
- Drop cached `original_code_prefix` field; compute inline with a
`keep in sync with pallet-gear-program::OriginalCodeStorage` note
- Inline single-use `map_err_into_rpc_err` helper; promote 9000 to
`ERROR_CODE` const
- Standardize error formatting on `Display` (was a mix of `{:?}` and
`to_string()`) so RPC errors don't leak struct internals
- Avoid SCALE double-allocation by decoding the `Compact<u32>` length
prefix and slicing into the storage buffer directly
- Delete WHAT-narration comments
- core/src/code/utils.rs: drop multi-line comment defending an
implementation detail already covered by the doc comment
- gsdk/tests/rpc.rs: drop WHAT-narration comments in
test_read_wasm_custom_section
- gsdk/src/rpc.rs: clarify in the doc that `block_hash: None` falls
back to the best block (preserving the trailing `at specified block`
required by the `#[at_block]` proc macro)
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
| // Keep in sync with `pallet-gear-program::OriginalCodeStorage` (StorageMap, Identity hasher). | ||
| let mut storage_key = twox_128(b"GearProgram").to_vec(); | ||
| storage_key.extend_from_slice(&twox_128(b"OriginalCodeStorage")); | ||
| storage_key.extend_from_slice(code_id.as_bytes()); |
There was a problem hiding this comment.
Move impl inside pallet gear, to use normally CodeStorage instead of this raw code
Summary
gear_readWasmCustomSection(code_id, section_name, at?)that reads custom sections from program WASM original code stored on-chainget_custom_section_data()utility ingear-corewith 5 unit testssails:idlWASM section without needing original build artifactsTest plan
get_custom_section_data(5 cases: found, not found, duplicates, invalid WASM, empty input)gear_readWasmCustomSectionvia RPCatparameter🤖 Generated with Claude Code